package com.pipi.sso.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.pipi.sso.core.enums.CommonStatusEnum;
import com.pipi.sso.core.enums.DormErrorCodeEnum;
import com.pipi.sso.core.exception.DormServiceException;
import com.pipi.sso.core.model.ClassesBO;
import com.pipi.sso.core.service.ClassesService;
import com.pipi.sso.core.util.BeanUtils;
import com.pipi.sso.dao.manager.ClassesManager;
import com.pipi.sso.dao.manager.CollegeManager;
import com.pipi.sso.dao.manager.StudentManager;
import com.pipi.sso.dao.model.ClassesDO;
import com.pipi.sso.dao.model.CollegeDO;
import com.pipi.sso.dao.model.StudentDO;
import com.pipi.sso.dao.query.ClassesQuery;
import com.pipi.sso.dao.query.StudentQuery;
import com.pipi.sso.dao.support.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.maihaoche.com
 *
 * @Package com.pipi.sso.core.service.impl
 * @date: 2019/4/7 5:04 PM
 * @Copyright: 2017-2020 www.maihaoche.com Inc. All rights reserved.
 */
@Service
@Slf4j
public class ClassesServiceImpl implements ClassesService {

    @Resource
    private ClassesManager classesManager;

    @Resource
    private CollegeManager collegeManager;

    @Resource
    private StudentManager studentManager;

    @Override
    public PageResult<ClassesBO> queryClassesByPaged(ClassesBO classesBO) {
        ClassesQuery query = buildQuery(classesBO);
        query.setPageNo(classesBO.getPage());
        query.setPageSize(classesBO.getLimit());
        try {
            PageResult<ClassesDO> pageResult = classesManager.selectByQueryWithPage(query);
            if (CollectionUtils.isEmpty(pageResult.getResult())) {
                return PageResult.createPageResult();
            }
            List<ClassesBO> classesBOS = buildClassesBOs(pageResult.getResult());
            return PageResult.createPageResult(classesBOS, pageResult.getPageInfo());
        } catch (Exception e) {
            log.error("查询班级信息失败！classesBO is {}", JSON.toJSONString(classesBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_CLASSES_FAIL);
        }
    }

    @Override
    public List<ClassesBO> queryClasses(ClassesBO classesBO) {
        try {
            ClassesQuery query = buildQuery(classesBO);
            List<ClassesDO> classesDOS = classesManager.selectByQuery(query);
            if (CollectionUtils.isEmpty(classesDOS)) {
                return Lists.newArrayList();
            }
            return buildClassesBOs(classesDOS);
        } catch (Exception e) {
            log.error("查询班级信息失败！classesBO is {}", JSON.toJSONString(classesBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_CLASSES_FAIL);
        }
    }

    @Override
    public Boolean addClasses(ClassesBO classesBO) {
        try {
            ClassesQuery query = buildQuery(classesBO);
            List<ClassesDO> classesDOS = classesManager.selectByQuery(query);
            if (CollectionUtils.isNotEmpty(classesDOS)) {
                throw new DormServiceException(DormErrorCodeEnum.CLASSES_IS_EXIST);
            }
            ClassesDO classesDO = BeanUtils.createCloneBean(classesBO, ClassesDO.class);
            classesDO.setIsDeleted(CommonStatusEnum.NO.getCode());
            // 查询学院信息
            CollegeDO collegeDO = collegeManager.selectByPrimaryKey(classesBO.getCollegeId());
            if (null == collegeDO || CommonStatusEnum.NO.getCode().equals(collegeDO.getStatus())) {
                throw new DormServiceException(DormErrorCodeEnum.COLLEGE_NOT_EXIST_OR_DISENABLE);
            }
            classesDO.setCollegeName(collegeDO.getCollegeName());
            classesManager.insertSelective(classesDO);
            return true;
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("添加班级信息失败！classesBO is {}" ,JSON.toJSONString(classesBO), e);
            throw new DormServiceException(DormErrorCodeEnum.ADD_CLASSES_FAIL);
        }
    }

    @Override
    public Boolean updateClasses(ClassesBO classesBO) {
        try {
            // 查询修改的班级信息是否已经存在
            ClassesQuery query = new ClassesQuery();
            query.createCriteria().andCollegeIdEqualTo(classesBO.getCollegeId())
                    .andProfessionEqualTo(classesBO.getProfession())
                    .andGradeEqualTo(classesBO.getGrade())
                    .andClassesEqualTo(classesBO.getClasses())
                    .andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
            List<ClassesDO> classesDOS = classesManager.selectByQuery(query);
            if (CollectionUtils.isNotEmpty(classesDOS)) {
                throw new DormServiceException(DormErrorCodeEnum.CLASSES_IS_EXIST);
            }
            // 判断学院是否被禁用
            CollegeDO collegeDO = collegeManager.selectByPrimaryKey(classesBO.getCollegeId());
            if (null == collegeDO || CommonStatusEnum.NO.getCode().equals(collegeDO.getStatus())) {
                throw new DormServiceException(DormErrorCodeEnum.COLLEGE_NOT_EXIST_OR_DISENABLE);
            }
            ClassesDO classesDO = BeanUtils.createCloneBean(classesBO, ClassesDO.class);
            classesDO.setCollegeName(collegeDO.getCollegeName());
            classesManager.updateByPrimaryKeySelective(classesDO);
            return true;
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新班级信息失败！classesBO is {}", JSON.toJSONString(classesBO), e);
            throw new DormServiceException(DormErrorCodeEnum.UPDATE_CLASSES_FAIL);
        }
    }

    @Override
    public void deleteClasses(List<Long> classIds) {
        try {
            // 如果班级有学生，就不给删除
            StudentQuery studentQuery = new StudentQuery();
            studentQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode()).andClassIdIn(classIds);
            List<StudentDO> studentDOS = studentManager.selectByQuery(studentQuery);
            if (CollectionUtils.isNotEmpty(studentDOS)) {
                log.error("班级还有学生！无法删除, classId is {}", JSON.toJSONString(classIds));
                throw new DormServiceException(DormErrorCodeEnum.CON_NOT_DELETE_CLASSES_HAVE_STUDENTS);
            }
            ClassesDO classesDO = new ClassesDO();
            classesDO.setIsDeleted(CommonStatusEnum.YES.getCode());
            ClassesQuery classesQuery = new ClassesQuery();
            classesQuery.createCriteria().andClassIdIn(classIds);
            classesManager.updateByQuerySelective(classesDO, classesQuery);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除班级失败！classIds is {}", JSON.toJSONString(classIds), e);
            throw new DormServiceException(DormErrorCodeEnum.DELETE_CLASSES_FAIL);
        }
    }

    private ClassesQuery buildQuery(ClassesBO classesBO) {
        ClassesQuery query = new ClassesQuery();
        query.setOrderByClause("gmt_create desc");
        ClassesQuery.Criteria criteria = query.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
        if (null != classesBO) {
            if (null != classesBO.getClassId()) {
                criteria.andClassIdEqualTo(classesBO.getClassId());
            }
            if (null != classesBO.getCollegeId()) {
                criteria.andCollegeIdEqualTo(classesBO.getCollegeId());
            }
            if (StringUtils.isNotBlank(classesBO.getCollegeName())) {
                criteria.andCollegeNameEqualTo(classesBO.getCollegeName());
            }
            if (StringUtils.isNotBlank(classesBO.getProfession())) {
                criteria.andProfessionLike("%" + classesBO.getProfession() + "%");
            }
            if (null != classesBO.getClasses()) {
                criteria.andClassesEqualTo(classesBO.getClasses());
            }
        }
        return query;
    }

    private List<ClassesBO> buildClassesBOs(List<ClassesDO>  classesDOS) {
        if (CollectionUtils.isEmpty(classesDOS)) {
            return Lists.newArrayList();
        }
        return classesDOS.stream().map(this::buildClassesBO).collect(Collectors.toList());
    }

    private ClassesBO buildClassesBO(ClassesDO classesDO) {
        if (classesDO == null) {
            return null;
        }
        ClassesBO classesBO = BeanUtils.createCloneBean(classesDO, ClassesBO.class);
        StudentQuery studentQuery = new StudentQuery();
        studentQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode())
                .andClassIdEqualTo(classesDO.getClassId());
        int studentNumber = studentManager.countByQuery(studentQuery);
        classesBO.setStudentNumber(studentNumber);
        return classesBO;

    }
}
